#include "thread_get_desktop_icon.h"
#include "qt_windows.h"

//引用顺序很重要
#include <windows.h>
#include <shlobj.h>
#include <shellapi.h>
#include <CommCtrl.h>
#include <initguid.h>
#include <commoncontrols.h>
#include <mmdeviceapi.h>
#include <endpointvolume.h>

#include <QSettings>
#include <QDir>
#include <QProcess>

//static int itt = 0;

ThreadGetDesktopIcon::ThreadGetDesktopIcon(QObject *parent)
    : QThread{parent}
{
    const_icon_map_.insert("doc",":/img_res/fake_desktop_icon/img_word_97_file_64.png");
    const_icon_map_.insert("docx",":/img_res/fake_desktop_icon/img_word_file_64.png");
    const_icon_map_.insert("ppt",":/img_res/fake_desktop_icon/img_ppt_file_64.png");
    const_icon_map_.insert("pptx",":/img_res/fake_desktop_icon/img_ppt_file_64.png");
    const_icon_map_.insert("xls",":/img_res/fake_desktop_icon/img_excel_file_64.png");
    const_icon_map_.insert("xlsx",":/img_res/fake_desktop_icon/img_excel_file_64.png");
    const_icon_map_.insert("txt",":/img_res/fake_desktop_icon/img_text_file_64.png");
    const_icon_map_.insert("zip",":/img_res/fake_desktop_icon/img_zip_64.png");
    const_icon_map_.insert("7z",":/img_res/fake_desktop_icon/img_zip_64.png");
    const_icon_map_.insert("rar",":/img_res/fake_desktop_icon/img_zip_64.png");
    const_icon_map_.insert("tar",":/img_res/fake_desktop_icon/img_zip_64.png");
    const_icon_map_.insert("bz2",":/img_res/fake_desktop_icon/img_zip_64.png");
}

ThreadGetDesktopIcon::~ThreadGetDesktopIcon()
{

}

void ThreadGetDesktopIcon::SetParam()
{

}

QList<DesktopIcon> ThreadGetDesktopIcon::GetResult()
{
    return result_list_;
}

void ThreadGetDesktopIcon::run()
{
    QSettings current_user_desktop_setting("HKEY_CURRENT_USER\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\User Shell Folders", QSettings::NativeFormat);
    QString current_user_desktop_path = current_user_desktop_setting.value("Desktop").toString();

    QStringList environment_path = QProcess::systemEnvironment();
    QString user_profile;
    QStringList::const_iterator c_iter = environment_path.cbegin();
    while(c_iter != environment_path.cend())
    {
        if((*c_iter).contains("USERPROFILE",Qt::CaseInsensitive))
        {
            user_profile = (*c_iter);
            user_profile = user_profile.split("=")[1];
            break;
        }
        ++c_iter;
    }

    current_user_desktop_path.replace(QString("%USERPROFILE%"),user_profile);
    qDebug() << current_user_desktop_path;

    QSettings public_desktop_setting("HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders", QSettings::NativeFormat);
    QString public_desktop_path = public_desktop_setting.value("Common Desktop").toString();

    QDir current_user_desktop_dir(current_user_desktop_path);
    QDir public_desktop_dir(public_desktop_path);

    QFileInfoList cu_list = current_user_desktop_dir.entryInfoList();
    QFileInfoList pub_list = public_desktop_dir.entryInfoList();

    QFileInfoList::iterator iter = cu_list.begin();
    while(iter != cu_list.end())
    {
        if((*iter).fileName() == "." || (*iter).fileName() == "..")
        {
            iter = cu_list.erase(iter);
            continue;
        }
        ++iter;
    }

    iter = pub_list.begin();
    while(iter != pub_list.end())
    {
        if((*iter).fileName() == "." || (*iter).fileName() == "..")
        {
            iter = pub_list.erase(iter);
            continue;
        }
        ++iter;
    }

    QFileInfoList::const_iterator const_iter = cu_list.constBegin();
    while(const_iter != cu_list.constEnd())
    {
        if(!pub_list.contains((*const_iter)))
        {
            pub_list.append((*const_iter));
        }
        ++const_iter;
    }

    result_list_.clear();
    result_list_.append(DesktopIcon(false, QImage(":/img_res/fake_desktop_icon/img_this_pc_64.png"), QString("此电脑")));

    //获取驱动器盘符
    DWORD DSLength = GetLogicalDriveStrings(0, NULL);
    LPTSTR lpDriveStrings = (LPTSTR)HeapAlloc(GetProcessHeap(), 0, DSLength*sizeof(TCHAR));
    QStringList driver_list;
    bool is_recycle_bin_full = false;
    //通过GetLogicalDriveStrings()函数获取所有驱动器字符串信息长度。
    GetLogicalDriveStrings(DSLength, lpDriveStrings);
    int si = 0;
    for (DWORD i = 0; i<(DSLength / 4); ++i)
    {
        char  dir2[3] = { static_cast<char>(lpDriveStrings[si]), ':', '\0' }; //盘符ABCD等
        driver_list.append(dir2);
        si += 4;
    }

    SHQUERYRBINFO query_info;
    query_info.cbSize = (DWORD)(sizeof(SHQUERYRBINFO));

    QList<QString>::const_iterator driver_iter = driver_list.constBegin();
    while(driver_iter != driver_list.constEnd())
    {
        QString driver_tmp = QString("%1\\").arg((*driver_iter));
        LPCWSTR driver_path_wc = reinterpret_cast<const LPCWSTR>(driver_tmp.utf16());

        SHQueryRecycleBin(driver_path_wc,&query_info);
        qint64 info_total = query_info.i64NumItems;

        is_recycle_bin_full = info_total > 0 ? true : false;
        if(is_recycle_bin_full)
        {
            break;
        }
        ++driver_iter;
    }

    if(is_recycle_bin_full)
    {
        result_list_.append(DesktopIcon(false, QImage(":/img_res/fake_desktop_icon/img_recycle_bin_full_64.png"), QString("回收站")));
    }
    else
    {
        result_list_.append(DesktopIcon(false, QImage(":/img_res/fake_desktop_icon/img_recycle_bin_empty_64.png"), QString("回收站")));
    }

    const_iter = pub_list.constBegin();
    while(const_iter != pub_list.constEnd())
    {
        QImage img;
        if((*const_iter).isSymLink())
        {
            GetIcon((*const_iter), (*const_iter).symLinkTarget(), img);
        }
        else
        {
            GetIcon((*const_iter), (*const_iter).absoluteFilePath(), img);
        }
        DesktopIcon desktop_icon((*const_iter).isDir(), img, (*const_iter).completeBaseName());
        result_list_.append(desktop_icon);
        ++const_iter;
    }
}

void ThreadGetDesktopIcon::GetIcon(const QFileInfo &info, QString file_path, QImage &img)
{ 
    if(info.isDir())
    {
        img.load(":/img_res/fake_desktop_icon/img_full_folder_64.png");
    }
    else if(!info.isDir())
    {
        QString dd = info.suffix();
        QString path = const_icon_map_.value(info.suffix(),"");
        if(!path.isEmpty())
        {
            img.load(path);
        }
        else
        {
            file_path.replace(QString("/"),QString("\\"));
            const auto *file_path_wc = reinterpret_cast<const wchar_t *>(file_path.utf16());

            SHFILEINFOW shell_file_info;
            ZeroMemory(&shell_file_info, sizeof(SHFILEINFO));
            SHGetFileInfo(file_path_wc, -1, &shell_file_info, sizeof(shell_file_info),
                          SHGFI_SYSICONINDEX);

            IImageList *image_list;
            HRESULT h_result =
                SHGetImageList(SHIL_EXTRALARGE, IID_IImageList, (void **)&image_list);

            if (S_OK == h_result)
            {
                int i = 0;
                if (SUCCEEDED(image_list->GetImageCount(&i)) && i > 0)
                {
                    HICON icon;
                    if (SUCCEEDED(image_list->GetIcon(shell_file_info.iIcon,
                                                    ILD_TRANSPARENT, &icon)))
                    {
                      img = QImage::fromHICON(icon);
                      //img.save(QString("test%1.png").arg(++itt));
                      DestroyIcon(icon);
                    }
                }
            }
        }
    }


}
